﻿using FreeSql;
using FreeSql.Internal;
using FreeSql.Internal.CommonProvider;
using System;
using System.Threading;

namespace TK.FreeSqlExtension
{
    /// <summary>
    /// MultiFreeSql
    /// </summary>
    public class MultiFreeSql : BaseDbProvider, IFreeSql
    {
        internal string _dbkeyMaster;
        BaseDbProvider _ormCurrent => _ib.Get(string.IsNullOrWhiteSpace(SplitInfo.Value?.DbKey) ? _dbkeyMaster : SplitInfo.Value?.DbKey) as BaseDbProvider;
        internal readonly IdleBus<string, IFreeSql> _ib;

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="timeSpan">对象空闲时间，超过释放掉</param>
        public MultiFreeSql(TimeSpan timeSpan)
        {
            _ib = new IdleBus<string, IFreeSql>(timeSpan);
            _ib.Notice += (_, __) => { };
        }

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="idleBus">IdleBus实例</param>
        public MultiFreeSql(IdleBus<string, IFreeSql> idleBus)
        {
            _ib = idleBus;
        }

        /// <summary>
        /// 分库分表
        /// </summary>
        public AsyncLocal<SplitInfo> SplitInfo => new AsyncLocal<SplitInfo>();

        public override IAdo Ado => _ormCurrent.Ado;

        public override IAop Aop => _ormCurrent.Aop;

        public override ICodeFirst CodeFirst => _ormCurrent.CodeFirst;

        public override IDbFirst DbFirst => _ormCurrent.DbFirst;

        public override GlobalFilter GlobalFilter => _ormCurrent.GlobalFilter;

        public override void Dispose() => _ib.Dispose();

        public override CommonExpression InternalCommonExpression => _ormCurrent.InternalCommonExpression;
        public override CommonUtils InternalCommonUtils => _ormCurrent.InternalCommonUtils;

        public override ISelect<T1> CreateSelectProvider<T1>(object dywhere) => _ormCurrent.CreateSelectProvider<T1>(dywhere);

        public override IDelete<T1> CreateDeleteProvider<T1>(object dywhere) => _ormCurrent.CreateDeleteProvider<T1>(dywhere);

        public override IUpdate<T1> CreateUpdateProvider<T1>(object dywhere) => _ormCurrent.CreateUpdateProvider<T1>(dywhere);

        public override IInsert<T1> CreateInsertProvider<T1>() => _ormCurrent.CreateInsertProvider<T1>();

        public override IInsertOrUpdate<T1> CreateInsertOrUpdateProvider<T1>() => _ormCurrent.CreateInsertOrUpdateProvider<T1>();
    }
}
